package com.atguigu.springboot.plugin;

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Statement;
import java.util.*;


//把一行数据封装成Map之后，{t_id=1, t_name=老师1}{t_id=2, t_name=老师2}
//在对象中还是习惯使用驼峰表示法，不喜欢使用下划线风格的编程，期望把Map中key中的下划线去掉，使用驼峰表示法
//{tId=1,tName=老师1}
/*
* 来标注要对哪一组件中哪一个方法做拦截增强
*
*   组件有四个：Executor,StatementHandler,ParameterHandler,ResultSetHandler
* */
@Intercepts(@Signature(
        type=ResultSetHandler.class,    //对ResultSetHandler组件中handleResultSets（Statement st）方法做增强
        method="handleResultSets",
        args={Statement.class}
        ))
public class CamelCaseInterceptor implements Interceptor {

    private Properties properties;
    //如何做增强的细节
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Map<String,Object> map;
        List<Object> list= (List<Object>) invocation.proceed();    //放行
        for (Object obj:list) {
            if(!(obj instanceof Map)){
                break;
            }
            //如果每一行数据的封装对象是Map的实例
            handleMap((Map<String, Object>) obj);
        }
        return list;
    }

    private void handleMap(Map<String,Object> map) {
        Set<String> keySet=new HashSet<>(map.keySet());
        for (String key : keySet){
            //判断key是否是大写字母开头或者带有下划线
            if(key.startsWith("A") && key.endsWith("Z") || key.contains("_")){
                Object value=map.get(key);
                map.remove(key);

                String newKey=handleKey(key);
                map.put(newKey, value);
            }
        }
    }

    private String handleKey(String key) {
        StringBuilder sb=new StringBuilder(10);

        boolean findUnderLine=false;
        for (int index=0;index<key.length();index++){
            char ch=key.charAt(index);
            if(ch=='_'){
                findUnderLine=true; //找到下划线
            }else {
                if(findUnderLine){
                    sb.append(Character.toUpperCase(ch));
                    findUnderLine=false;
                }else {
                    sb.append(Character.toLowerCase(ch));
                }
            }
        }
        return sb.toString();
    }

    //包装
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    //给拦截器设置配置参数，配置可以由使用拦截器的人来给定
    @Override
    public void setProperties(Properties properties) {
        this.properties=properties;
    }
}
